﻿#
# views.py
# 
# Bug tracking system
#
import os
from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.http import HttpResponseForbidden
from django.http import Http404
from django.template import RequestContext, Context
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.db.models.loading import get_model

from models import Project, Task, History, Tag
from forms import TaskForm
from forms import TaskBugHistoryForm, TaskFeatureHistoryForm
from homesite.bugs import globals


#from django.contrib.auth.decorators import permission_required
#@permission_required('polls.can_vote', login_url="/permission_denied/")


SEVERITY_ORDER = ['Dream','Minor','Normal','Major']

def file_exists(name):
    exists = 0
    if "access" in os.__dict__.keys():
        exists = os.access (name, os.F_OK)
    else:
        try:
            fp = open (name, "r")
            fp.close()
            exists = 1
        except:
            pass
    return exists


def handle_uploaded_file(f):
    name = f.name
    path = 'D:/srv/www/django/homesite/media/attach/'
    file_path = '%s%s' % (path, name)
    i = 0
    while file_exists(file_path):
        name = '%s_%i' % (f.name, i)
        file_path = '%s%s' % (path, name)        
        i = i + 1
        if i > 1000:
            pass
    destination = open(file_path, 'wb+')
    for chunk in f.chunks():
        destination.write(chunk)
    return name    


def error_403():
    return render_to_response('403.html')



#def user_in_proj(user_id, proj_id):
#   return
def default_proc(request):
    "A context processor."
    user_name = request.user
    return {
        'user_name': user_name,
    }



@login_required
def index(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname)
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403() 
    context = Context({
      'project': project,
    })
    return render_to_response('bugs/index.html', context, context_instance=RequestContext(request, processors=[default_proc]))



@login_required
def projectselect(request):
    projectslist = Project.objects.filter(users__id=request.user.id)
    return render_to_response('bugs/projectselect.html', locals())



@login_required
def newbug(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname)
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #    
    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            taskinst = form.save(commit=False)
            taskinst.serial = Task.objects.filter(project = project.id).count() + 1   
            taskinst.severityorder = SEVERITY_ORDER.index(taskinst.severity)
            taskinst.save()
            h = History(task=taskinst, action='Task Created', user=request.user)
            h.save();
            return HttpResponseRedirect(reverse('homesite.bugs.views.activetask', args=[project.norm_name]))
    else:
        form = TaskForm(initial={'project':project.id, 'kind':'Bug', 'severity':'Normal','status':'Open','reporter':request.user.id,'owner':request.user.id})
    context = Context({
      'form': form,
      'project': project, 
    })        
    return render_to_response('bugs/form_bug_add.html', context, context_instance=RequestContext(request, processors=[default_proc]))



@login_required
def newfeature(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname)
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #    

    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            taskinst = form.save(commit=False)
            taskinst.serial = Task.objects.filter(project = project.id).count() + 1
            taskinst.severityorder = SEVERITY_ORDER.index(taskinst.severity)
            taskinst.save()
            h = History(task=taskinst, action='Task Created', user=request.user)
            h.save();
            return HttpResponseRedirect(reverse('homesite.bugs.views.activetask', args=[project.norm_name]))
    else:
        form = TaskForm(initial={'project':project.id, 'kind':'Feature', 'severity':'Normal','status':'New','reporter':request.user.id,'owner':request.user.id})
    context = Context({
      'form': form,
      'project': project, 
    })          
    return render_to_response('bugs/form_feature_add.html', context, context_instance=RequestContext(request, processors=[default_proc]))



@login_required
def alltask(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname)
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #
    tasklist = Task.objects.select_related().filter(project = project.id)
    context = Context({
      'project': project,
      'tasklist': tasklist, 
    }) 
    return render_to_response('bugs/task_all.html', context, context_instance=RequestContext(request, processors=[default_proc]))


 
@login_required 
def activetask(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname) 
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #
    q1 = Task.objects.select_related().filter(project = project.id)
    tasklist = q1.exclude(status='Resolved')
    context = Context({
      'project': project,
      'tasklist': tasklist, 
    })    
    return render_to_response('bugs/task_active.html', context, context_instance=RequestContext(request, processors=[default_proc]))


@login_required 
def curusertask(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname) 
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #
    q1 = Task.objects.select_related().filter(project = project.id)
    q2 = q1.filter(owner=request.user)
    tasklist = q2.exclude(status='Resolved')
    context = Context({
      'project': project,
      'tasklist': tasklist, 
    })
    return render_to_response('bugs/task_curuser.html', context, context_instance=RequestContext(request, processors=[default_proc]))



@login_required 
def resolved(request, prjname):
    project = get_object_or_404(Project, norm_name = prjname) 
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #
    tasklist = Task.objects.select_related().filter(project = project.id, status='Resolved')
    context = Context({
      'tasklist': tasklist,
      'project': project,
    })
    return render_to_response('bugs/task_resolved.html', context, context_instance=RequestContext(request, processors=[default_proc]))

 
@login_required 
def taskinfo(request, prjname, taskid):
    project = get_object_or_404(Project, norm_name = prjname) 
    taskitem = get_object_or_404(Task, id = taskid)
    #check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403() 
    # 
    taskhistory = History.objects.select_related().filter(task=taskid)
    globals.project_norm_name = project.norm_name
    if request.method == 'POST':
        if taskitem.kind == 'Bug':
            form = TaskBugHistoryForm(request.POST, request.FILES, instance=taskitem)
        else:
            form = TaskFeatureHistoryForm(request.POST, request.FILES, instance=taskitem)
        if form.is_valid():
            faction = ''
            attach_file = ''
            attach_file_name = ''
            if request.FILES.has_key('attachment'):
                attach_file_name = handle_uploaded_file(request.FILES['attachment'])
                #faction = faction + 'file attached<br/>'
                attach_file = request.FILES['attachment'].name
                
                
            if taskitem.severity !=  form.cleaned_data['severity']:
                faction = faction + 'changed Severity from <b>"%s"</b> to <b>"%s"</b><br/>' % (taskitem.severity, form.cleaned_data['severity'])

            if taskitem.owner !=  form.cleaned_data['owner']:
                faction = faction + 'changed Owner from <b>"%s"</b> to <b>"%s"</b><br/>' % (taskitem.owner.username, form.cleaned_data['owner'].username)

            if taskitem.summary !=  form.cleaned_data['summary']:
                faction = faction + 'changed Summary from<br/><b>%s</b><br/>to<br/><b>%s</b><br/>' % (taskitem.summary, form.cleaned_data['summary'])

            if taskitem.description !=  form.cleaned_data['description']:
                faction = faction + 'changed Description from<br/><b>%s</b><br/>to<br/><b>%s</b><br/>' % (taskitem.description, form.cleaned_data['description'])

            new = list(get_model('bugs', 'Tag').objects.filter(id__in=form.cleaned_data['tags']))
            old = taskitem.tags.all()
            add = [t for t in new if t not in old ]
            delete = [t for t in old if t not in new]
            for t in add:
                faction = faction + 'add Tags <b>%s</b><br/>' % t
            for t in delete:
                faction = faction + 'delete Tags <b>%s</b><br/>' % t

            # status
            status_form = form.save(commit=False)
            #status_form.resolution = taskitem.resolution
            status_form.severityorder = SEVERITY_ORDER.index(status_form.severity)
            new_status = request.POST.get('new_status', '')
            if new_status != '':
                if taskitem.status !=  new_status:
                    faction = faction + 'changed Status from <b>"%s"</b> to <b>"%s"</b><br/>' % (taskitem.status, new_status)
                    status_form.status = new_status
                    
            if (faction != '') or (form.cleaned_data['comment'] != '') or (attach_file != ''):        
                h = History(task=taskitem, comment=form.cleaned_data['comment'], action=faction, user=request.user, attachment=attach_file, attachmentname=attach_file_name)
                h.save() 
            
            status_form.save()
            form.save_m2m() 
            return HttpResponseRedirect(reverse('homesite.bugs.views.taskinfo', args=[project.norm_name,taskid]))
    else:
        if taskitem.kind == 'Bug':
            form = TaskBugHistoryForm(instance=taskitem)#TaskBugHistoryForm   -BugHistoryForm
        else:
            form = TaskFeatureHistoryForm(instance=taskitem)
    context = Context({
      'form': form,
      'project': project,
      'taskhistory':taskhistory,
      'taskitem':taskitem,
    })            
    return render_to_response('bugs/taskinfo.html', context, context_instance=RequestContext(request, processors=[default_proc]))


@login_required
def tasktags(request, prjname, tags):
    project = get_object_or_404(Project, norm_name = prjname) 
    # check user in project
    users = User.objects.filter(project__id=project.id)
    if not request.user in users:
        return error_403()
    #
    tasklist = Task.objects.filter(tags__value=tags, project=project.id)
    context = Context({
      'tasklist': tasklist,
      'project': project,
    })
    return render_to_response('bugs/tags_list.html', context, context_instance=RequestContext(request, processors=[default_proc]))

